package com.diligent.cloud.sfc.service.impl;

import com.alibaba.fastjson.JSON;
import com.canny.commons.model.Codes;
import com.canny.commons.model.ListResult;
import com.canny.commons.model.ObjectResult;
import com.canny.commons.model.Result;
import com.canny.commons.page.IPage;
import com.canny.commons.page.Pagination;
import com.codingapi.txlcn.tc.annotation.LcnTransaction;
import com.diligent.cloud.logistics.container.enums.BoxStatus;
import com.diligent.cloud.logistics.container.model.LcmBoxLedger;
import com.diligent.cloud.logistics.container.service.LcmBoxLedgerFeignService;
import com.diligent.cloud.primary.data.feign.service.mdm.MdmMatTypeFeignService;
import com.diligent.cloud.primary.data.model.mdm.MdmMatType;
import com.diligent.cloud.prodbatch.model.MfgProdBatch;
import com.diligent.cloud.prodbatch.service.MfgProdBatchFeignService;
import com.diligent.cloud.sfc.model.MatType;
import com.diligent.cloud.sfc.model.info.PowderSummary;
import com.diligent.cloud.sfc.model.info.ProdBatchInfo;
import com.diligent.cloud.sfc.service.ProdBatchService;
import com.diligent.cloud.web.model.PageAndCondition;
import com.diligent.cloud.workorder.model.WoOperationCompleteDetail;
import com.diligent.cloud.workorder.model.WoOperationCompleteParams;
import com.diligent.cloud.workorder.model.WoOrder;
import com.diligent.cloud.workorder.service.WoOperationCompleteDetailFeignService;
import com.diligent.cloud.workorder.service.WoOperationCompleteFeignService;
import com.diligent.cloud.workorder.service.WoOrderFeignService;
import com.diligent.cloud.workordermd.feign.service.MfgConsumeDetailFeignService;
import com.diligent.cloud.workordermd.feign.service.MfgConsumeMasterFeignService;
import com.diligent.cloud.workordermd.feign.service.MfgMdApplyUseFeignService;
import com.diligent.cloud.workordermd.model.MfgConsumeDetail;
import com.diligent.cloud.workordermd.model.MfgConsumeMaster;
import com.diligent.cloud.workordermd.model.MfgMdApplyUse;
import com.diligent.foundation.data.model.v2.Condition;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.security.Principal;
import java.util.*;

/**
 * ProdBatchServiceImpl class
 *
 * @author xf107278
 * @date 4/2/2020
 */
@Service
public class ProdBatchServiceImpl implements ProdBatchService {

    private MfgProdBatchFeignService mfgProdBatchFeignService;
    private MfgMdApplyUseFeignService mfgMdApplyUseFeignService;
    private MfgConsumeDetailFeignService mfgConsumeDetailFeignService;
    private WoOrderFeignService orderFeignService;
    private MfgConsumeMasterFeignService mfgConsumeMasterFeignService;
    private MdmMatTypeFeignService mdmMatTypeFeignService;
    private WoOperationCompleteDetailFeignService operationCompleteDetailFeignService;
    private final WoOperationCompleteFeignService operationCompleteFeignService;
    private final LcmBoxLedgerFeignService boxLedgerFeignService;

    public ProdBatchServiceImpl(MfgProdBatchFeignService mfgProdBatchFeignService,
                                MfgMdApplyUseFeignService mfgMdApplyUseFeignService,
                                MfgConsumeDetailFeignService mfgConsumeDetailFeignService,
                                WoOrderFeignService orderFeignService,
                                MfgConsumeMasterFeignService mfgConsumeMasterFeignService,
                                MdmMatTypeFeignService mdmMatTypeFeignService,
                                WoOperationCompleteDetailFeignService operationCompleteDetailFeignService,
                                WoOperationCompleteFeignService operationCompleteFeignService
            , LcmBoxLedgerFeignService boxLedgerFeignService) {
        this.mfgProdBatchFeignService = mfgProdBatchFeignService;
        this.mfgMdApplyUseFeignService = mfgMdApplyUseFeignService;
        this.mfgConsumeDetailFeignService = mfgConsumeDetailFeignService;
        this.orderFeignService = orderFeignService;
        this.mfgConsumeMasterFeignService = mfgConsumeMasterFeignService;
        this.mdmMatTypeFeignService = mdmMatTypeFeignService;
        this.operationCompleteDetailFeignService = operationCompleteDetailFeignService;
        this.operationCompleteFeignService = operationCompleteFeignService;
        this.boxLedgerFeignService = boxLedgerFeignService;
    }

    @Override
    public ResponseEntity<Result> updateBatchStatus(String prodBatch, Long systemId, Principal principal) {
        ResponseEntity<com.diligent.cloud.primary.data.model.Result> update =
                mfgProdBatchFeignService.update(prodBatch, systemId, principal);
        ObjectResult result;
        if (update.getBody() != null) {
            result = new ObjectResult(update.getBody().getCode());
            result.modifyCode(update.getBody().getCode(), update.getBody().getMsg());
        } else {
            result = new ObjectResult();
        }
        return ResponseEntity.ok(result);
    }

    @Override
    @Transactional
    @LcnTransaction
    public ResponseEntity<Result> cancellationProdBatch(Long mdId, String prodBatch, Long systemId, Long orderId,
                                                        Principal principal) {

        mfgProdBatchFeignService.update(prodBatch, systemId, principal);
        //作废批要将模变回加温状态
        ResponseEntity<com.diligent.cloud.primary.data.model.Result<MfgMdApplyUse>> byId =
                mfgMdApplyUseFeignService.getById(String.valueOf(mdId));
        if (byId.getBody() == null) {
            ObjectResult result = new ObjectResult();
            result.modifyCode(Codes.fail.getCode(), Strings.lenientFormat("查询不到此[%s]模具", mdId));
            return ResponseEntity.ok(result);
        }
        MfgMdApplyUse mfgMdApplyUse = byId.getBody().getData();
        mfgMdApplyUse.setDocStatus(50);
        mfgMdApplyUse.setModifyCode(principal.getName());
        mfgMdApplyUse.setModifyName(principal.getName());
        mfgMdApplyUse.setModifyTime(new Date());

        mfgMdApplyUseFeignService.modify(mfgMdApplyUse);

        ResponseEntity<com.diligent.cloud.primary.data.model.Result> orderResult =
                orderFeignService.selectById(orderId);
        Preconditions.checkNotNull(orderResult.getBody(), "工单为空");
        WoOrder order = (WoOrder) orderResult.getBody().getData();
        PageAndCondition pageAndCondition = new PageAndCondition();
        pageAndCondition.setPagination(new Pagination(1L, 10000L));
        List<Condition> conditions = new ArrayList<>();

        conditions.add(new Condition("prodBatch", "eq", prodBatch, null));
        conditions.add(new Condition("woOrder", "eq", order.getWoOrder(), null));

        pageAndCondition.setConditions(conditions);
        ResponseEntity<com.diligent.cloud.primary.data.model.Result<IPage<WoOperationCompleteDetail>>> operationCompleteDetailPage =
                operationCompleteDetailFeignService.page(pageAndCondition);

        if (operationCompleteDetailPage.getBody() != null && operationCompleteDetailPage.getBody().getData().getRecords().size() != 0) {
            WoOperationCompleteDetail operationCompleteDetail =
                    Optional.of(operationCompleteDetailPage.getBody().getData().getRecords().stream().findFirst().get()).get();
            operationCompleteDetail.setProdBatch("null");
            operationCompleteDetail.setModifyTime(new Date());
            operationCompleteDetail.setModifyName(principal.getName());
            operationCompleteDetail.setModifyCode(principal.getName());

            operationCompleteDetailFeignService.update(operationCompleteDetail);
        }

        return ResponseEntity.ok(new ObjectResult<>());
    }


    @Override
    public ResponseEntity<ObjectResult> getBatch(String machCode, Long systemId, Principal principal) {
        PageAndCondition pageAndCondition = new PageAndCondition();
        Pagination pagination = new Pagination(1L, 1000000L);
        List<Condition> conditions = new ArrayList<>();
        conditions.add(new Condition("machCode", "eq", machCode, null));
        conditions.add(new Condition("endTime", "nn", 0, null));
        conditions.add(new Condition("systemId", "eq", systemId, null));
        conditions.add(new Condition("processType", "nn", 0, null));

        pageAndCondition.setPagination(pagination);
        pageAndCondition.setConditions(conditions);
        ResponseEntity<com.diligent.cloud.primary.data.model.Result<IPage<MfgProdBatch>>> search =
                mfgProdBatchFeignService.search(pageAndCondition);
        ObjectResult result;
        if (search.getBody() != null && search.getBody().getData().getRecords().size() != 0) {
            List<ProdBatchInfo> answer = new ArrayList<>();
            for (MfgProdBatch prodBatch : search.getBody().getData().getRecords()) {
                ProdBatchInfo prodBatchInfo = new ProdBatchInfo();
                prodBatchInfo.setProdBatch(prodBatch.getProdBatch());
                getProdBatchInfoByProdBatch(prodBatch,
                        prodBatchInfo, false);

                prodBatchInfo.setSystemId(prodBatch.getSystemId());

                answer.add(prodBatchInfo);
            }
            if (answer.size() == 1) {

                if (answer.get(0).getWoOrder() == null) {
                    answer = new ArrayList<>();
                }
            }
            result = new ObjectResult(answer);
            result.modifyCode(Codes.success.getCode(), Codes.success.getMsg());

        } else {
            result = new ObjectResult(new ArrayList<>());
            result.modifyCode(Codes.success.getCode(), "无未结束生产批");
        }
        return ResponseEntity.ok(result);
    }

    @Override
    public ResponseEntity<ObjectResult> getLastOneBatch(String machCode, Long systemId, Principal principal) {
        ResponseEntity<com.diligent.cloud.primary.data.model.Result<MfgProdBatch>> byBatchLast =
                mfgProdBatchFeignService.getByBatchLast(machCode, systemId);
        if (byBatchLast.getBody() != null && byBatchLast.getBody().getData() != null) {
            MfgProdBatch mfgProdBatch = byBatchLast.getBody().getData();
            ProdBatchInfo prodBatchInfo = new ProdBatchInfo();

            prodBatchInfo.setProdBatch(mfgProdBatch.getProdBatch());
            getProdBatchInfoByProdBatch(mfgProdBatch,
                    prodBatchInfo, true);
            prodBatchInfo.setSystemId(mfgProdBatch.getSystemId());

            ObjectResult result = new ObjectResult(prodBatchInfo);
            result.modifyCode(Codes.success.getCode(),
                    Codes.success.getMsg());
            return ResponseEntity.ok(result);
        } else {
            ObjectResult result = new ObjectResult(null);
            result.modifyCode(Codes.success.getCode(), "无未结束的生产批");
            return ResponseEntity.ok(result);
        }
    }

    @Override
    public ResponseEntity<ObjectResult> getLastOneBatchByCart(String machCode, Long systemId, Principal principal) {
        ResponseEntity<com.diligent.cloud.primary.data.model.Result<MfgProdBatch>> byBatchLast =
                mfgProdBatchFeignService.getByBatchLastCar(machCode, systemId);
        if (byBatchLast.getBody() != null && byBatchLast.getBody().getData() != null) {
            MfgProdBatch mfgProdBatch = byBatchLast.getBody().getData();
            PageAndCondition pageAndCondition = new PageAndCondition();
            pageAndCondition.setPagination(new Pagination(1L, 1L));
            List<Condition> conditions = new ArrayList<>();
            conditions.add(new Condition("code", "eq", mfgProdBatch.getMatCode(), null));
            conditions.add(new Condition("state", "eq", BoxStatus.NORMAL.getStatus(), null));
            pageAndCondition.setConditions(conditions);
            ResponseEntity<com.diligent.cloud.primary.data.model.Result> search =
                    boxLedgerFeignService.search(pageAndCondition);
            if (search.getBody() != null && ((IPage<LcmBoxLedger>) search.getBody().getData()).getRecords().size() != 0) {
                LcmBoxLedger lcmBoxLedger =
                        Optional.of(((IPage<LcmBoxLedger>) search.getBody().getData()).getRecords().stream().findFirst().get()).get();
                ObjectResult result = new ObjectResult(lcmBoxLedger);
                result.modifyCode(Codes.success.getCode(), mfgProdBatch.getProdBatch());
                return ResponseEntity.ok(result);
            }
        }

        ObjectResult result = new ObjectResult(null);
        result.modifyCode(Codes.success.getCode(), "无未结束的生产批");
        return ResponseEntity.ok(result);

    }

    @Override
    public ResponseEntity<ObjectResult> getMatStatisticsConsumeByProdBatch(String startTime, String endTime) {
        PageAndCondition pageAndCondition = new PageAndCondition();
        pageAndCondition.setPagination(new Pagination(1L, 100000000000000L));
        List<Condition> conditions = new ArrayList<>();
        conditions.add(new Condition("beginTime", "ge", startTime, null));
        conditions.add(new Condition("endTime", "le", endTime, null));
        pageAndCondition.setConditions(conditions);
        ResponseEntity<com.diligent.cloud.primary.data.model.Result<IPage<MfgProdBatch>>> prodBatchPage =
                mfgProdBatchFeignService.search(pageAndCondition);

        ObjectResult result;
        BigDecimal totalWeight = new BigDecimal(0);
        BigDecimal totalReturnWeight = new BigDecimal(0);
        if (prodBatchPage.getBody() != null && prodBatchPage.getBody().getData().getRecords().size() != 0) {
            for (MfgProdBatch prodBatch : prodBatchPage.getBody().getData().getRecords()) {
                ResponseEntity<com.diligent.cloud.primary.data.model.Result> consumerMasterResult =
                        mfgConsumeMasterFeignService.selectDataByCondition(Collections.singletonList(new Condition(
                                "prodBatch", "eq", prodBatch.getProdBatch(), null)));
                if (consumerMasterResult.getBody() != null && consumerMasterResult.getBody().getCode() == 0) {
                    List<LinkedHashMap> consumerMasterList =
                            (List<LinkedHashMap>) consumerMasterResult.getBody().getData();
                    for (LinkedHashMap consumerMasterMap : consumerMasterList) {
                        MfgConsumeMaster consumeMaster =
                                JSON.parseObject(JSON.toJSONString(consumerMasterMap),
                                        MfgConsumeMaster.class);

                        ResponseEntity<com.diligent.cloud.primary.data.model.Result> matTypeResult =
                                mdmMatTypeFeignService.selectDataByCondition(Collections.singletonList(new Condition(
                                        "code", "eq", consumeMaster.getMatType(), null)));

                        if (matTypeResult.getBody() != null && matTypeResult.getBody().getCode() == 0) {

                            List<LinkedHashMap> matTypeList = (List<LinkedHashMap>) matTypeResult.getBody().getData();
                            for (LinkedHashMap matTypeMap : matTypeList) {
                                MdmMatType matType = JSON.parseObject(JSON.toJSONString(matTypeMap),
                                        MdmMatType.class);

                                if (MatType.粉末.equalsIgnoreCase(matType.getName())) {
                                    totalWeight = totalWeight.add(consumeMaster.getWeight());
                                    totalReturnWeight = totalReturnWeight.add(consumeMaster.getReturnWeight());
                                }
                            }
                        }
                    }
                }
            }
            return ResponseEntity.ok(new ObjectResult(new PowderSummary(totalWeight, totalReturnWeight)));
        } else {
            result = new ObjectResult();
            result.modifyCode(Codes.success.getCode(), "此时间段内无生产批信息");
        }
        return ResponseEntity.ok(result);
    }

    @Override
    public ResponseEntity<ListResult> getProdBatchByMachCode(String machCode, Integer isFinished, Long pageIndex,
                                                             Long pageSize) {
        ResponseEntity<com.diligent.cloud.primary.data.model.Result> responseEntity =
                operationCompleteFeignService.selectProdBatchs(machCode, isFinished, pageIndex, pageSize);

        if (responseEntity.getBody() == null && responseEntity.getBody().getData() == null) {
            return ResponseEntity.ok(new ListResult());
        }
        List<String> prodBatchList = (List<String>) responseEntity.getBody().getData();
        List<Map> mfgProdBatches = new ArrayList<>();
        for (String prodBatch : prodBatchList) {
            com.diligent.cloud.primary.data.model.Result result =
                    mfgProdBatchFeignService.getByBatch(prodBatch).getBody();
            if (result.getData() != null) {
                List<Map> list = (List) result.getData();
                mfgProdBatches.add(Optional.of(list.stream().findFirst().get()).get());
            }
        }
        ListResult listResult = new ListResult(mfgProdBatches);
        listResult.modifyCode(Codes.success.getCode(), responseEntity.getBody().getMsg());
        return ResponseEntity.ok(listResult);
    }

    private void getProdBatchInfoByProdBatch(MfgProdBatch prodBatch, ProdBatchInfo prodBatchInfo, Boolean last) {
        PageAndCondition pageAndCondition = new PageAndCondition();
        List<Condition> conditions = new ArrayList<>();
        List<WoOrder> answer = new ArrayList<>();


        WoOperationCompleteParams woOperationCompleteParams = new WoOperationCompleteParams();
        pageAndCondition.setPagination(new Pagination(1L, 1000000L));
        woOperationCompleteParams.setPageIndex(1L);
        woOperationCompleteParams.setPageSize(1000000L);
        woOperationCompleteParams.setProdBatch(prodBatch.getProdBatch());
        if (last) {
            woOperationCompleteParams.setIsFinished(1);
        } else {
            woOperationCompleteParams.setIsFinished(0);
        }
        pageAndCondition.setConditions(conditions);

        //根据批次信息查询消耗表找到铝棒信息
        ResponseEntity<com.diligent.cloud.primary.data.model.Result> consumeMasterResult =
                mfgConsumeMasterFeignService.selectDataByCondition(Collections.singletonList(new Condition(
                        "prodBatch", "eq", prodBatch.getProdBatch(), null)));
        if (consumeMasterResult.getBody() != null && consumeMasterResult.getBody().getCode() == 0) {
            List<LinkedHashMap> consumeMasters = (List<LinkedHashMap>) consumeMasterResult.getBody().getData();

            MfgConsumeMaster mfgConsumeMaster =
                    JSON.parseObject(JSON.toJSONString(consumeMasters.stream().findFirst().get()),
                            MfgConsumeMaster.class);
            ResponseEntity<com.diligent.cloud.primary.data.model.Result> consumerDetailResult =
                    mfgConsumeDetailFeignService.selectDataByCondition(Collections.singletonList(
                            new Condition("masterId", "eq", mfgConsumeMaster.getId(), null)));
            if (consumerDetailResult.getBody() != null && consumerDetailResult.getBody().getCode() == 0) {
                List<LinkedHashMap> consumerDetails =
                        (List<LinkedHashMap>) consumerDetailResult.getBody().getData();
                MfgConsumeDetail consumeDetail =
                        JSON.parseObject(JSON.toJSONString(consumerDetails.stream().findFirst().get()),
                                MfgConsumeDetail.class);
                prodBatchInfo.setLotCode(consumeDetail.getLotCode());
                //添加铝棒id
                prodBatchInfo.setAsId(mfgConsumeMaster.getId());
            }
        }

        ResponseEntity<com.diligent.cloud.primary.data.model.Result> mdApplyUserResult =
                mfgMdApplyUseFeignService.selectDataByCondition(Collections.singletonList(new Condition(
                        "matCodeCv", "eq", prodBatch.getMatCode(), null)));
        if (mdApplyUserResult.getBody() != null) {
            List<LinkedHashMap> mdApplyUserList = (List<LinkedHashMap>) mdApplyUserResult.getBody().getData();
            if (mdApplyUserList.size() == 0) {
                throw new NullPointerException(Strings.lenientFormat("查询不到[%s]摸具", prodBatch.getMatCode()));
            }
            MfgMdApplyUse mfgMdApplyUse =
                    JSON.parseObject(JSON.toJSONString(mdApplyUserList.stream().findFirst().get()),
                            MfgMdApplyUse.class);
            prodBatchInfo.setMatCodeCv(mfgMdApplyUse.getMatCodeCv());
            prodBatchInfo.setMatCode(mfgMdApplyUse.getMatCode());
            prodBatchInfo.setMatId(mfgMdApplyUse.getId());
        }

        //查询批次查询工序完工单
        ResponseEntity<com.diligent.cloud.primary.data.model.Result> operationCompleteDetailPage =
                operationCompleteDetailFeignService.selectOperationComplete(woOperationCompleteParams);

        if (operationCompleteDetailPage.getBody() != null && ((ArrayList<LinkedHashMap>) operationCompleteDetailPage.getBody().getData()).size() != 0) {
            ArrayList<LinkedHashMap> operationCompleteDetailList =
                    (ArrayList<LinkedHashMap>) operationCompleteDetailPage.getBody().getData();
            WoOperationCompleteDetail operationCompleteDetail =
                    JSON.parseObject(JSON.toJSONString(operationCompleteDetailList.stream().findFirst().get()),
                            WoOperationCompleteDetail.class);
            if (operationCompleteDetail.getStartTime() == null) {
                return;
            }
            pageAndCondition.setConditions(Collections.singletonList(new Condition("woOrder", "eq",
                    operationCompleteDetail.getWoOrder(), null)));
            ResponseEntity<com.diligent.cloud.primary.data.model.Result<IPage<WoOrder>>> orderPage =
                    orderFeignService.page(pageAndCondition);
            if (orderPage.getBody()!=null && orderPage.getBody().getData().getRecords().size() != 0) {
                answer.add(orderPage.getBody().getData().getRecords().stream().findFirst().get());
            }
            prodBatchInfo.setWoOrder(answer);
        }


        return;

    }

}
